﻿/*
 * Twipler - Twitter Web Client with features.
 *  
 *  Copyright (C) 2009, 2010. Ian Quigley
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details. 
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 */

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Twipler.App.Machine
{
	public class StaticMethodCall
	{

		public StaticMethodCall()
		{
		}

		public StaticMethodCall(MethodInfo methodInfo, List<Variable> parameters)
		{
			_methodInfo = methodInfo;
			Params = parameters;
		}

		private readonly MethodInfo _methodInfo;

		public string MethodName;

		public List<Variable> Params { get; set; }

		public Type ReturnType { get { return _methodInfo.ReturnType;  } }


		public override string ToString()
		{
			return ToString(false);
		}

		public string ToString(bool withoutParenthesis)
		{
			StringBuilder name = new StringBuilder();
			name.AppendFormat("{0}{1}", MethodName, withoutParenthesis ? "" : "(");

			if (Params != null)
			{
				foreach (Variable var in Params)
				{
					name.AppendFormat("{0},", var.Value);
				}
				name.Remove(name.Length - 1, 1);
			}

			if (!withoutParenthesis)
				name.Append(")");

			return name.ToString();
		}

		/// <summary>
		/// Execute the method call
		/// </summary>
		/// <param name="environment">Execution environment or NULL if out of context</param>
		/// <returns></returns>
		public object Invoke(Environment environment)
		{
			object[] obj = new object[Params.Count];
			for (int i = 0; i < Params.Count; i++)
			{
				object var = Params[i].Value;
				if (var is StaticMethodCall)
					var = ((StaticMethodCall)var).Invoke(environment);

				if ((var is string) && (environment != null) && (!string.IsNullOrEmpty((string)var)) && (((string)var)[0] == '?'))
					var = environment.Variables_Get(((string)var).Substring(1));

				obj[i] = var;
			}

			return _methodInfo.Invoke(null, obj);
		}
	}
}